#!/usr/bin/env python3
"""
===============================================================================
FURRYOS SMART EXTRACTOR PATCH
===============================================================================
Fixes "Failed to extract vmlinuz" error.
The script will now scan the ISO's /live/ directory to find the ACTUAL 
kernel filenames (which include version numbers) instead of guessing.
===============================================================================
"""
import os
import sys

# The updated deploy_iso.py content with smart extraction
NEW_DEPLOY_CODE = r'''#!/usr/bin/env python3
"""
===============================================================================
FURRYOS DEPLOYER: SMART EXTRACT EDITION
===============================================================================
Features:
1. Auto-detects Debian Live ISO.
2. INTELLIGENTLY finds kernel files (vmlinuz-*) inside the ISO.
3. Extracts and renames them to standard names for easy booting.
===============================================================================
"""
import os
import shutil
import subprocess
import hashlib
import sys
import glob
from pathlib import Path

# --- Configuration ---
VERSION = "8.2.0-live"
BUILD_DIR = Path("furryos_build")
ISO_WORK = BUILD_DIR / "iso_workspace"
OUTPUT_DIR = Path("output")
ASSETS_DIR = Path("assets")
ANTHROHEART_SRC = Path("ANTHROHEART")

def run_cmd(cmd, desc):
    print(f"⚡ {desc}...")
    try:
        subprocess.run(cmd, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        print(f"❌ Error: {e}")
        sys.exit(1)

def find_live_iso():
    """Auto-detects the Debian Live ISO in assets/"""
    isos = list(ASSETS_DIR.glob("debian-live-*.iso"))
    if not isos:
        print("❌ No Live ISO found in assets/!")
        sys.exit(1)
    selected_iso = sorted(isos)[-1]
    print(f"✅ Detected Base System: {selected_iso.name}")
    return selected_iso

def setup_workspace():
    print("🧹 Cleaning workspace...")
    if ISO_WORK.exists(): shutil.rmtree(ISO_WORK)
    dirs = ["boot/grub", "live", "furryos/bin", "furryos/assets", "furryos/source"]
    for d in dirs:
        (ISO_WORK / d).mkdir(parents=True, exist_ok=True)

def get_iso_file_list(iso_path):
    """Runs xorriso to list files in /live inside the ISO"""
    cmd = ["xorriso", "-indev", str(iso_path), "-ls", "/live"]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print("❌ Failed to list ISO contents.")
        return []
    
    # Parse output to get filenames
    files = []
    for line in result.stdout.splitlines():
        parts = line.split()
        if parts:
            filename = parts[-1].strip("'") # Get last part, remove quotes
            if filename not in [".", ".."]:
                files.append(filename)
    return files

def extract_live_system(iso_path):
    print("🐧 Extracting Live Kernel & Filesystem...")
    
    # 1. Find the real filenames inside the ISO
    print("   Scanning ISO structure...")
    iso_files = get_iso_file_list(iso_path)
    
    real_kernel = next((f for f in iso_files if f.startswith("vmlinuz")), None)
    real_initrd = next((f for f in iso_files if f.startswith("initrd")), None)
    real_fs = next((f for f in iso_files if f.startswith("filesystem.squashfs")), None)

    if not real_kernel or not real_initrd or not real_fs:
        print("❌ CRITICAL: Could not find kernel/initrd/filesystem in ISO /live/ folder.")
        print(f"   Found files: {iso_files}")
        sys.exit(1)

    print(f"   ✓ Found Kernel: {real_kernel}")
    print(f"   ✓ Found Initrd: {real_initrd}")
    print(f"   ✓ Found FS:     {real_fs}")

    dest_live = ISO_WORK / "live"
    
    # 2. Extract and Rename
    # We extract the complex name (vmlinuz-6.1...) but save it as simple 'vmlinuz'
    # This matches our GRUB config perfectly.
    
    extract_map = {
        real_kernel: "vmlinuz",
        real_initrd: "initrd.img",
        real_fs: "filesystem.squashfs"
    }

    for iso_file, local_name in extract_map.items():
        print(f"   Extracting {iso_file} -> {local_name}...")
        cmd = f"xorriso -osirrox on -indev '{iso_path}' -extract /live/{iso_file} {dest_live}/{local_name}"
        try:
            subprocess.run(cmd, shell=True, check=True, stderr=subprocess.DEVNULL)
        except subprocess.CalledProcessError:
            print(f"   ⚠️  Failed to extract {iso_file}")
            sys.exit(1)

def copy_anthroheart():
    if ANTHROHEART_SRC.exists():
        print(f"📦 Found ANTHROHEART Library! Copying...")
        dest = ISO_WORK / "furryos/ANTHROHEART"
        cmd = f"rsync -a --info=progress2 '{ANTHROHEART_SRC}/' '{dest}/'"
        run_cmd(cmd, "Copying Media Library")

def copy_source_code():
    print("🧬 Embedding Source Code...")
    src_dest = ISO_WORK / "furryos/source"
    files = ["quick_start.sh", "setup_venv.sh", "GENOME.yaml", "USER_CONFIG.yaml"]
    for f in files:
        if Path(f).exists(): shutil.copy2(f, src_dest)
    
    ignore = shutil.ignore_patterns("furryos_build", "output", "*.iso", "__pycache__", "venv")
    if Path("assets").exists(): shutil.copytree("assets", src_dest / "assets", ignore=ignore)
    if Path("images").exists(): shutil.copytree("images", src_dest / "images")

def populate_binaries():
    print("📦 Copying Binaries...")
    src_bin = BUILD_DIR / "bin"
    if src_bin.exists():
        for f in src_bin.glob("*"):
            shutil.copy2(f, ISO_WORK / "furryos/bin")
    
    etcher = list(Path("assets").glob("balenaEtcher*.AppImage"))
    if etcher:
        shutil.copy2(etcher[0], ISO_WORK / "furryos/assets")

def create_grub_config():
    print("📝 Creating Live GRUB Config...")
    cfg = r"""
set default=0
set timeout=5

menuentry "FurryOS Live (Desktop)" {
    linux /live/vmlinuz boot=live components quiet splash persistence
    initrd /live/initrd.img
}

menuentry "FurryOS Live (RAM Mode)" {
    linux /live/vmlinuz boot=live components toram quiet splash
    initrd /live/initrd.img
}

menuentry "FurryOS Live (Safe Graphics)" {
    linux /live/vmlinuz boot=live components nomodeset
    initrd /live/initrd.img
}
"""
    with open(ISO_WORK / "boot/grub/grub.cfg", "w") as f:
        f.write(cfg)

def build_iso(base_iso_name):
    clean_base_name = base_iso_name.replace('.iso', '')
    iso_name = f"furryos-{VERSION}-based_on-{clean_base_name}.iso"
    
    print(f"\n💿 Building Final ISO: {iso_name}...")
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    output_iso = OUTPUT_DIR / iso_name
    
    cmd = f"grub-mkrescue -o '{output_iso}' {ISO_WORK} -- -volid 'FURRYOS_LIVE'"
    run_cmd(cmd, "Generating Hybrid ISO")
    
    if output_iso.exists():
        size_gb = output_iso.stat().st_size / (1024**3)
        print(f"\n✅ SUCCESS! ISO Created.")
        print(f"   Path: {output_iso}")
        print(f"   Size: {size_gb:.2f} GB")

def main():
    base_iso = find_live_iso()
    setup_workspace()
    extract_live_system(base_iso.name) # <--- SMART EXTRACTOR
    copy_anthroheart()
    copy_source_code()
    populate_binaries()
    create_grub_config()
    build_iso(base_iso.name)

if __name__ == "__main__":
    main()
'''

def apply_patch():
    target = "assets/deploy_iso.py"
    print(f"🐺 Patching {target} with Smart Extractor...")
    try:
        with open(target, "w", encoding="utf-8") as f:
            f.write(NEW_DEPLOY_CODE)
        os.chmod(target, 0o755)
        print("✅ Patch Successful!")
        print("   Run './quick_start.sh' to build.")
    except Exception as e:
        print(f"❌ Error writing file: {e}")

if __name__ == "__main__":
    apply_patch()
